package com.grj.parking.drools.config;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.benmanes.caffeine.cache.Cache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * 多级缓存操作工具类
 */
@Slf4j
@Component
public class MultiLevelCacheService {

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;


    @Autowired
    @Qualifier("allLocalCache")
    private Cache<String, Object> allLocalCache;



    // ------------------------------ 通用缓存操作 ------------------------------
    /**
     * 获取闸口缓存（多级缓存）
     */
    public <T> T getCache(String id, Class<T> clazz, String type) {

        String redisKey = CacheConstants.CACHE_KEY_PREFIX + type +":" + id;

        // 1. 查询本地缓存
        Object localValue = allLocalCache.getIfPresent(redisKey);
        if (localValue != null) {
            return clazz.cast(localValue);
        }

        try {
            // 2. 查询Redis缓存
            String redisValue = (String) redisTemplate.opsForValue().get(redisKey);
            if (redisValue != null) {
                T result = objectMapper.readValue(redisValue, clazz);
                // 同步到本地缓存
                allLocalCache.put(redisKey, result);
                return result;
            }
        } catch (Exception e) {
            log.error("获取缓存异常，ID:{}", redisKey, e);
        }

        // 缓存未命中
        return null;
    }

    /**
     * 设置闸口缓存（多级缓存）
     */
    public <T> void setCache(String id, T value, String type) {
        String redisKey = CacheConstants.CACHE_KEY_PREFIX + type +":"+ id;
        try {

            // 1. 更新Redis缓存
            // 2. 更新本地缓存
            allLocalCache.put(redisKey, value);
            redisTemplate.opsForValue().set(
                    redisKey,
                    objectMapper.writeValueAsString(value),
                    CacheConstants.CACHE_EXPIRE,
                    TimeUnit.MILLISECONDS
            );
        } catch (JsonProcessingException e) {
            log.error("设置缓存异常，ID:{}", redisKey, e);
        }
    }

    /**
     * 删除闸口缓存（多级缓存）
     */
    public void deleteCache(String id, String type) {
        String redisKey = CacheConstants.CACHE_KEY_PREFIX + type +":"+ id;

        // 1. 删除本地缓存
        allLocalCache.invalidate(redisKey);

        // 2. 删除Redis缓存
        redisTemplate.delete(redisKey);
    }
}
